<?php


namespace servers;


class RedisServer
{
    //私有静态属性保存静态类的实例化
    private static $redis=null;

    //防止类被实例化
    private function __construct()
    {
        self::$redis = new \Yii::$app->redis;
        self::$redis->select(6);
    }

    //防止类外被克隆
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    //入口文件
    public static function entrance()
    {
        if(empty(self::$redis)){
            return new RedisServer();
        }
        return self::$redis;
    }

    /**
     * 添加redis对列
     * @param $key
     * @param string $val
     * @param int $passTime
     * @return mixed
     * @cyf
     */
    public function lpush($key,$val='',$passTime=30)
    {
        return self::$redis->lpush($key,$val);
    }

    /**
     * 移除redis队列
     * @param $key
     * @return mixed
     * @cyf
     */
    public function lpop($key)
    {
        return self::$redis->lpop($key);
    }

    /**
     * redis上锁
     * @param $uid
     * @param string $key
     * @param int $time
     * @return bool
     * @cyf
     */
    public function setnx($uid,$key='lock',$time=3)
    {
        $is_lock = self::$redis->setnx($uid.$key,time()+$time);//添加锁
        if(!$is_lock){//判断上锁是否成功 false 说明锁存在
            $getlock = self::$redis->get($uid.$key);
            $nowTime = time();
            if($nowTime<$getlock) return false;
            $this->delnx($uid.$key);
        }
        return $getlock ? false : true;
    }

    /**
     * 删除锁
     * @param $key
     * @cyf
     */
    public function delnx($key)
    {
       $bool =  self::$redis->del($key);
       return $bool;
    }


    /**
     * 签到
     * @param $uid
     * @cyf
     */
    public function signAdd($uid,$date)
    {
        $key ='sign'.date('Y_m').'_'.$uid;//设置用户每月签到信息的key值
        $timestamp = strtotime($date);
        $offset =(int)date('d',$timestamp);//偏移量  表示这个月的第几天
        $is_exit = $this->getSign($uid,$date);
        if($is_exit == '1') return false;
        //签到
        $set = self::$redis->setbit($key,$offset,true);

        return true;

    }

    /**
     * 获取签到信息
     * @param $key
     * @param $offset
     * @cyf
     */
    public function getSign($uid,$date)
    {
        $key ='sign'.date('Y_m').'_'.$uid;//设置用户每月签到信息的key值
        $timestamp = strtotime($date);
        $offset =(int)date('d',$timestamp);//偏移量  表示这个月的第几天
        return self::$redis->getbit($key,$offset); //

    }
    /**
     * 获取签到天数
     * @param $key
     * @return mixed
     * @cyf
     */
    public function getSignDay($uid,$date)
    {
        $timestamp = strtotime($date);
        $yearMonth = date('Y_m',$timestamp);
        $key ='sign'.$yearMonth.'_'.$uid;//设置用户每月签到信息的key值
        $count = self::$redis->bitcount($key);
        return $count;
    }

    /**
     * 查看连续签到天数
     * @param $uid
     */
    public function getField($uid,$date='')
    {
        if($date == '') $date = date('Y-m-d');//如果不传时间默认是今天
        $key ='sign'.date('Y_m').'_'.$uid;//设置用户每月签到信息的key值
       $timestamp = strtotime($date);//获取时间戳
        $day = (int)date('d',$timestamp);//获取当前天数
        $offset = 'u'.$day; //获取查询天数
        $arr = self::entrance()->bitfield($key,'GET',$offset,1)[0]; //得到十进制本月签到信息
        $detail = decbin($arr);
        $count = 0;
        for($i=strlen($detail)-1;$i>=0;$i--){
            if($detail[$i] == 1){
                $count++;
            }else{
                break;
            }
        }
        return $count;
    }

    /**
     * 订阅
     */
    public function psubscribe($scribes)
    {
        $res = self::$redis->PUBSUB($scribes);
        print_r($res);die();
    }
}